package com.zzuli.yxy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzuli.yxy.entity.*;
import com.zzuli.yxy.enumeration.AppHttpCodeEnum;
import com.zzuli.yxy.result.R;
import com.zzuli.yxy.util.TXCloudFileUtils;
import com.zzuli.yxy.mapper.AlbumMapper;
import com.zzuli.yxy.mapper.CommentMapper;
import com.zzuli.yxy.mapper.ThumbsMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.zzuli.yxy.service.AlbumService;

import java.util.ArrayList;
import java.util.List;

/**
 * @auther pony
 * @create 2023-04-04 22:43
 */
@Service
public class AlbumServiceImpl extends ServiceImpl<AlbumMapper, Album> implements AlbumService {

    @Autowired
    private AlbumMapper albumMapper;

    @Autowired
    private CommentMapper commentMapper;

    @Autowired
    private ThumbsMapper thumbsMapper;

    //腾讯云对象存储 路径-访问域名
    private static String url = "https://pony-1312090731.cos.ap-beijing.myqcloud.com/";
    // 图片存储的文件夹
    private static String imgPath = "yxy/images/";

    /**
     * 获取专辑管理分页信息
     * @param pageCurrent 当前页
     * @param pageSize 每页条数
     * @param name 关键字 非必传
     * @return
     */
    @Override
    public R getPage(Integer pageCurrent, Integer pageSize, String name) {
        // 1、查询分页信息
        Page<Album> pageInfo = new Page<>(pageCurrent, pageSize);
        LambdaQueryWrapper<Album> qw = new LambdaQueryWrapper<>();
        qw.like(name!=null, Album::getAlbumName, name);
        Page<Album> albumPage = albumMapper.selectPage(pageInfo, qw);
        System.out.println("albumPage=" + albumPage);
        // 2、设置专辑的歌手信息、歌曲信息
        List<Album> albumList = albumPage.getRecords();
        for (Album album: albumList) {
            // 查询专辑的歌手
            List<Singer> singerList = albumMapper.selectSingerByAlbumId(album.getAlbumId());
            ArrayList<String> singerNameList = new ArrayList<>();
            for (Singer singer : singerList) {
                singerNameList.add(singer.getSingerName());
            }
            album.setSingerNameList(singerNameList);

            // 查询专辑下的所有歌
            List<Song> songList = albumMapper.selectSongByAlbumId(album.getAlbumId());
            // 准备一个 list 存放专辑的所有歌曲名
            ArrayList<String> songNameList = new ArrayList<>();
            for (Song song : songList) {
                songNameList.add(song.getSongName());
            }
            album.setSongNameList(songNameList);
        }
        return R.success(AppHttpCodeEnum.SUCCESS, "专辑分页信息").data("albumPage", albumPage);
    }

    /**
     * 更改专辑当前状态
     * @param id 专辑 id
     * @param status 状态码 0：正常 1：异常
     * @return
     */
    @Override
    public void setStatus(Integer id, Integer status) {
        LambdaUpdateWrapper<Album> uw = new LambdaUpdateWrapper<>();
        uw.eq(Album::getAlbumId, id);
        uw.set(Album::getAlbumStatus, status);
        albumMapper.update(null, uw);
    }

    /**
     * 添加专辑-添加专辑名、专辑状态、专辑发行时间、专辑发行公司、专辑简介
     * 专辑图片，请参考下面的各自的上传方法
     * @param album
     * @return
     */
    @Override
    public R addAlbum(Album album) {
        // 1、添加专辑
        int insert = albumMapper.insert(album);
        if(insert==1){
            // 2、返回前端提示信息
            return R.success(AppHttpCodeEnum.SUCCESS, "专辑添加成功！");
        }
        return R.error(AppHttpCodeEnum.ERROR, "专辑添加失败！");
    }

    /**
     * 添加专辑-上传专辑图片
     * 将文件上传到云端，然后将图片的访问路径暂时存储到浏览器，
     * 当用户点击提交按钮时，和基本数据一起存到数据库
     * @param file 图片
     * @return
     */
    @Override
    public R uploadAddImg(MultipartFile file) {
        //1、上传文件 返回值是 key，即图片重新命名的名字
        String imgName = TXCloudFileUtils.upLoad(imgPath, file);
        //2、拼接 img 访问路径，并写入数据库
        String imgUrl = url  + imgPath + imgName;
        return R.success(AppHttpCodeEnum.SUCCESS,"专辑图片上传成功").data("albumImgUrl", imgUrl);
    }

    /**
     * 根据专辑 id，删除专辑
     * 既要删除数据库里的关于此专辑的一切信息
     * 1、专辑数据
     * 2、专辑和歌手、专辑和歌曲关联关系
     * 又要删除专辑在 云存储桶里的 图片 数据
     * @param id 专辑id
     * @return
     */
    @Override
    public R deleteAlbumById(Integer id) {
        /*1、删除云存储桶里的专辑图片
        查询数据库 得到 专辑信息*/
        LambdaQueryWrapper<Album> selectQw = new LambdaQueryWrapper<>();
        selectQw.eq(Album::getAlbumId, id);
        Album selectResult = albumMapper.selectOne(selectQw);
        //2、删除云存储桶里的专辑 图片
        deleteTXCosAlbumImg(selectResult);

        //4、删除数据库里专辑基本信息
        LambdaQueryWrapper<Album> qw = new LambdaQueryWrapper<>();
        qw.eq(Album::getAlbumId, id);
        int deleteResult = albumMapper.delete(qw);

        //5、删除专辑 歌手的关联信息
        albumMapper.deleteSingerByAlbumId(id);
        //6、删除专辑 歌曲的关联信息
        albumMapper.deleteSongByAlbumId(id);

        //7、删除专辑的评论和评论的回复信息
        LambdaQueryWrapper<Comment> commentQw = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<Comment> replyQw = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<Thumbs> thumbsQw = new LambdaQueryWrapper<>();

        commentQw.eq(Comment::getRelevance, id);
        // 查询所有专辑的评论
        List<Comment> commentList = commentMapper.selectList(commentQw);
        // 删除所有专辑的评论
        commentMapper.delete(commentQw);

        // 删除所有专辑的评论的回复
        for (Comment comment : commentList) {
            // 删除所有专辑的评论的点赞信息
            thumbsQw.eq(Thumbs::getCommentId, comment.getId());

            replyQw.eq(Comment::getRelevance, comment.getId());
            List<Comment> replyList = commentMapper.selectList(replyQw);
            commentMapper.delete(replyQw);

            for (Comment reply : replyList) {
                // 删除所有专辑的评论的回复点赞信息
                thumbsQw.eq(Thumbs::getCommentId, reply.getId());
                thumbsMapper.delete(thumbsQw);
            }
        }

        //删除专辑信息
        if (deleteResult==1){
            return R.success(AppHttpCodeEnum.SUCCESS,"专辑删除成功");
        }
        return R.error(AppHttpCodeEnum.ERROR, "专辑删除失败，系统错误，请联系管理员");
    }

    /**
     * 删除云存储桶里的专辑 图片
     * @param album 待删除专辑
     */
    public void deleteTXCosAlbumImg(Album album){
        /*最初爬虫的专辑图片数据没有存到云存储桶 是网易的图片 不需要删，也删不了
        albumImg：http://p1.music.126.net/AAKrMZu-zyunLRqAMO9JlA==/109951166577890720.jpg?param=130y130
        而本系统添加的专辑时，图片是存储在云存储桶里的，需要删除
        albumImg：https://pony-1312090731.cos.ap-beijing.myqcloud.com/yxy/images/20230414093225fcb9570a89b44a1c94421e8239bbe3cf.jpg
        */
        String albumImg = album.getAlbumImg();

        // 删除云存储桶里的专辑图片
        if (albumImg!=null && !"".equals(albumImg)){
            //删除云存储桶里的专辑 图片（网易的不用删）, 只需要判断是否以 https 开头就行
            if (albumImg.startsWith("https")){
                //albumImgKey: 20230414093225fcb9570a89b44a1c94421e8239bbe3cf.jpg
                String albumImgKey = albumImg.substring(albumImg.indexOf("images/")+7);
                TXCloudFileUtils.del(imgPath+albumImgKey);
            }
        }
    }

    /**
     * 删除云存储桶里的专辑 图片
     * @param albumImg 图片地址
     */
    public void deleteTXCosAlbumImg(String albumImg){
        /*最初爬虫的专辑图片数据没有存到云存储桶 是网易的图片 不需要删，也删不了
        albumImg：http://p1.music.126.net/AAKrMZu-zyunLRqAMO9JlA==/109951166577890720.jpg?param=130y130
        而本系统添加的专辑时，图片是存储在云存储桶里的，需要删除
        albumImg：https://pony-1312090731.cos.ap-beijing.myqcloud.com/yxy/images/20230414093225fcb9570a89b44a1c94421e8239bbe3cf.jpg
        */
        // 删除云存储桶里的专辑图片
        if (albumImg!=null && !"".equals(albumImg)){
            //删除云存储桶里的专辑 图片（网易的不用删）, 只需要判断是否以 https 开头就行
            if (albumImg.startsWith("https")){
                //albumImgKey: 20230414093225fcb9570a89b44a1c94421e8239bbe3cf.jpg
                String albumImgKey = albumImg.substring(albumImg.indexOf("images/")+7);
                TXCloudFileUtils.del(imgPath+albumImgKey);
            }
        }
    }

    /**
     * 根据专辑id，查询单个专辑信息
     * @param id 专辑id
     * @return
     */
    @Override
    public R selectOneById(Integer id) {
        LambdaQueryWrapper<Album> qw = new LambdaQueryWrapper<>();
        qw.eq(Album::getAlbumId, id);
        Album album = albumMapper.selectOne(qw);
        return R.success(AppHttpCodeEnum.SUCCESS,"根据id，查询单个专辑数据").data("album", album);
    }

    /**
     * 修改专辑基本信息
     * @param album
     * @return
     */
    @Override
    public R updateAlbum(Album album) {
        //1、修改前，先删除之前专辑存在云端的图片
        // 根据 id 查询要删除的album
        LambdaQueryWrapper<Album> qw = new LambdaQueryWrapper<>();
        qw.eq(Album::getAlbumId, album.getAlbumId());
        Album selectOne = albumMapper.selectOne(qw);
        deleteTXCosAlbumImg(selectOne);
        //2、修改数据库里的专辑信息
        LambdaUpdateWrapper<Album> uw = new LambdaUpdateWrapper<>();
        uw.eq(Album::getAlbumId, album.getAlbumId());
        uw.set(Album::getAlbumName, album.getAlbumName());
        uw.set(Album::getAlbumStatus, album.getAlbumStatus());
        uw.set(Album::getAlbumRemarks, album.getAlbumRemarks());
        uw.set(Album::getAlbumReleaseTime, album.getAlbumReleaseTime());
        uw.set(Album::getAlbumCompany, album.getAlbumCompany());
        uw.set(Album::getAlbumImg, album.getAlbumImg());
        int updateResult = albumMapper.update(album, uw);
        //3、返回结果
        if (updateResult==1){
            return R.success(AppHttpCodeEnum.SUCCESS, "专辑修改成功");
        }
        return R.error(AppHttpCodeEnum.ERROR,"专辑修改失败，系统错误，请联系管理员");
    }

    /**
     * 批量删除
     * @param ids 专辑 id数组
     * @return
     */
    @Override
    public R deleteAlbumBatch(List<Integer> ids) {
        for (Integer id : ids) {
            /*1、删除云存储桶里的专辑图片
            查询数据库 得到 专辑信息*/
            LambdaQueryWrapper<Album> selectQw = new LambdaQueryWrapper<>();
            selectQw.eq(Album::getAlbumId, id);
            Album selectResult = albumMapper.selectOne(selectQw);
            //2、删除云存储桶里的专辑 图片
            deleteTXCosAlbumImg(selectResult);

            //4、删除数据库里专辑基本信息
            LambdaQueryWrapper<Album> qw = new LambdaQueryWrapper<>();
            qw.eq(Album::getAlbumId, id);
            int deleteResult = albumMapper.delete(qw);

            //5、删除专辑 歌手的关联信息
            albumMapper.deleteSingerByAlbumId(id);
            //6、删除专辑 歌曲的关联信息
            albumMapper.deleteSongByAlbumId(id);

            //7、删除专辑的评论和评论的回复信息
            LambdaQueryWrapper<Comment> commentQw = new LambdaQueryWrapper<>();
            LambdaQueryWrapper<Comment> replyQw = new LambdaQueryWrapper<>();
            LambdaQueryWrapper<Thumbs> thumbsQw = new LambdaQueryWrapper<>();

            commentQw.eq(Comment::getRelevance, id);
            // 查询所有专辑的评论
            List<Comment> commentList = commentMapper.selectList(commentQw);
            // 删除所有专辑的评论
            commentMapper.delete(commentQw);

            // 删除所有专辑的评论的回复
            for (Comment comment : commentList) {
                // 删除所有专辑的评论的点赞信息
                thumbsQw.eq(Thumbs::getCommentId, comment.getId());

                replyQw.eq(Comment::getRelevance, comment.getId());
                List<Comment> replyList = commentMapper.selectList(replyQw);
                commentMapper.delete(replyQw);

                for (Comment reply : replyList) {
                    // 删除所有专辑的评论的回复点赞信息
                    thumbsQw.eq(Thumbs::getCommentId, reply.getId());
                    thumbsMapper.delete(thumbsQw);
                }
            }

            if (deleteResult!=1){
                return R.error(AppHttpCodeEnum.ERROR, "批量删除失败，系统错误，请联系管理员");
            }
        }
        return R.success(AppHttpCodeEnum.SUCCESS, "批量删除成功");
    }

    /**
     * 为 专辑添加歌手信息
     * @param albumId 要添加的专辑id
     * @param singerId  要添加的歌手id ，-1 表示用户没传
     * @return
     */
    @Override
    public R addSingerForAlbum(Integer albumId, Integer singerId) {
        //添加前先删除 专辑有 关联的 歌手信息
        albumMapper.deleteSingerByAlbumId(albumId);
        Integer addSingerResult = albumMapper.addSingerForAlbum(singerId, albumId);
        if (addSingerResult!=1){
            return R.error(AppHttpCodeEnum.ERROR, "专辑添加歌手失败，系统错误，请联系管理员");
        }
        return R.success(AppHttpCodeEnum.SUCCESS, "专辑添加歌手成功");
    }
}
